package com.primestone.cim.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPReply;

/**
 * @author cesar.mateus
 * Oct 29, 2013 11:33:41 PM
 * CIMFTPClient.java
 * GetMeterReadingsClient
 * 
 */
public class CIMFTPClient {
	
	private final static Logger LOGGER = Logger.getLogger(CIMFTPClient.class.getName());

	private FTPClient ftp = null;
	
	/**
	 * 
	 */
	public static final int DEFAULT_PORT = 21;

	/**
	 * @param host
	 * @param user
	 * @param pwd
	 * @throws Exception
	 */
	public CIMFTPClient(String host, String user, String pwd) throws Exception {
		this(host, DEFAULT_PORT, user, pwd, true);
	}
	
	/**
	 * @param host
	 * @param port
	 * @param user
	 * @param pwd
	 * @throws Exception
	 */
	public CIMFTPClient(String host, int port, String user, String pwd) throws Exception {
		this(host, port, user, pwd, true);
	}
	
	/**
	 * @param host
	 * @param port 
	 * @param user
	 * @param pwd
	 * @param isBinaryFileType 
	 * @throws Exception
	 */
	public CIMFTPClient(String host, int port, String user, String pwd, boolean isBinaryFileType) throws Exception {
		this.ftp = new FTPClient();
		this.ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));
		int reply;
		try {
			this.ftp.connect(host, port);
			reply = this.ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				this.ftp.disconnect();
				throw new Exception("Exception connecting to FTP Server");
			}
		} catch (IOException e) {
            if (this.ftp.isConnected()) {
                try {
                    this.ftp.disconnect();
                } catch (IOException f) {
                    // do nothing
                }
            }
            LOGGER.log(Level.SEVERE, "Could not connect to server.");
            e.printStackTrace();
        }
		
		try {
			this.ftp.login(user, pwd);
			
			if (!this.ftp.login(user, pwd)) {
	            this.ftp.logout();
	        }
			
			if (isBinaryFileType) {
				this.ftp.setFileType(FTP.BINARY_FILE_TYPE);
			} else {
				this.ftp.setFileType(FTP.ASCII_FILE_TYPE);
			}
			
			this.ftp.enterLocalPassiveMode();
			
		} catch (FTPConnectionClosedException e) {
			LOGGER.log(Level.SEVERE, "Server closed connection.");
            e.printStackTrace();
        } catch (IOException e) {
        	LOGGER.log(Level.SEVERE, "input output exception.");
            e.printStackTrace();
        } finally {
//            if (this.ftp.isConnected()) {
//                try {
//                    this.ftp.disconnect();
//                } catch (IOException f) {
//                    // do nothing
//                }
//            }
        }
	}
	
	/**
	 * @param localFileFullName
	 * @param fileName
	 * @param hostDir
	 * @throws Exception
	 */
	public void uploadFile(String localFileFullName, String fileName, String hostDir) throws Exception {
//		try(InputStream input = new FileInputStream(new File(localFileFullName))){
//			this.ftp.storeFile(hostDir + fileName, input);
//		}
		InputStream input = null;
		try {
			input = new FileInputStream(new File(localFileFullName));
			LOGGER.log(Level.FINE, "--- null input: {0}", (input==null));
			LOGGER.log(Level.FINE, "--- hostDir: {0}", hostDir);
			LOGGER.log(Level.FINE, "--- fileName: {0}", fileName);
			
			this.ftp.storeFile(new StringBuilder(hostDir).append(fileName).toString(), input);
			LOGGER.log(Level.INFO, "---- getReplyCode: " + this.ftp.getReplyCode());
			//this.ftp.completePendingCommand();
		} finally {
			if (input != null) {
				input.close();
			}
		}
	}

	/**
	 * 
	 */
	public void disconnect(){
		if (this.ftp.isConnected()) {
			try {
				this.ftp.logout();
				this.ftp.disconnect();
			} catch (IOException f) {
				// do nothing as file is already saved to server
			}
		}
	}
	public static void main(String[] args) throws Exception {
		System.out.println("Start");
		CIMFTPClient ftpUploader = new CIMFTPClient("ftp.journaldev.com", 21, "ftpUser", "ftpPassword", true);
		//FTP server path is relative. So if FTP account HOME directory is "/home/pankaj/public_html/" and you need to upload 
		// files to "/home/pankaj/public_html/wp-content/uploads/image2/", you should pass directory parameter as "/wp-content/uploads/image2/"
		ftpUploader.uploadFile("D:\\Pankaj\\images\\MyImage.png", "image.png", "/wp-content/uploads/image2/");
		ftpUploader.disconnect();
		System.out.println("Done");
	}

}